package com.fy.market.strategy.service.raffle.template;

import com.fy.market.strategy.model.dto.UserQueryDTO;
import com.fy.market.strategy.model.entity.*;
import com.fy.market.strategy.model.entity.tree.valobj.RuleTreeVO;
import com.fy.market.strategy.model.enums.DeletedEnum;
import com.fy.market.strategy.model.enums.StatusEnum;
import com.fy.market.strategy.model.entity.tree.RuleTreeResultEntity;
import com.fy.market.strategy.repository.IStrategyRepository;
import com.fy.market.strategy.service.raffle.IRaffleStrategy;
import com.fy.market.types.common.reslut.R;
import com.fy.market.types.common.constant.ResultMessageConstant;
import com.fy.market.types.common.ex.ExHandler;
import com.fy.market.types.common.utils.FyObjUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

import static com.fy.market.types.common.reslut.R.ok;

/**
 * 抽奖策略抽象类 模板方法设计模式
 *
 * @author fwq
 * @date 2025-8-13 15:00
 * @desc 抽奖策略抽象类
 */
@Slf4j
public abstract class AbstractRaffleStrategy implements IRaffleStrategy {
    private IStrategyRepository iStrategyRepository;

    public AbstractRaffleStrategy(IStrategyRepository iStrategyRepository) {
        this.iStrategyRepository = iStrategyRepository;
    }

    /**
     * 抽奖
     *
     * @param ruleMatterEntity 抽奖因子实体类
     * @return R
     */
    @Override
    public R doRaffle(RuleMatterEntity ruleMatterEntity) {
        // 参数校验
        ExHandler.throwIf(ruleMatterEntity == null
                || ruleMatterEntity.getStrategyId() == null
                || ruleMatterEntity.getUserId() == null, ResultMessageConstant.PARAMS_ERROR);

        Integer strategyId = ruleMatterEntity.getStrategyId();
        Integer userId = ruleMatterEntity.getUserId();

        // 查询策略有效性
        StrategyEntity strategyEntity = iStrategyRepository.getStrategyEntity(strategyId);
        ExHandler.throwIf(strategyEntity == null, ResultMessageConstant.LotteryStrategy.STRATEGY_NOT_FOUND);

        // 查询用户有效性
        // 校验用户
        UserQueryDTO userQueryDTO = new UserQueryDTO();
        userQueryDTO.setId(userId);

//        UserEntity user = iStrategyRepository.getUserOne(userQueryDTO);
//        ExHandler.throwIf(user == null || FyObjUtil.isNullObj(user), ResultMessageConstant.USER_NOT_FOUND);
//        ExHandler.throwIf(DeletedEnum.DELETED.getCode().equals(user.getDeleted())
//                        || StatusEnum.DISABLE.getCode().equals(user.getStatus()),
//                ResultMessageConstant.ACCOUNT_ERROR);

        List<StrategyRuleModelEntity> ruleModelList = iStrategyRepository.getRuleModelList(strategyId);

        if (ruleModelList.isEmpty()) return ok("当前策略未配置任何规则!");

        // 抽奖前 - 规则过滤
        RuleChainResultEntity ruleChainResultEntity = this.doCheckRaffleBeforeLogic(ruleMatterEntity);

        if (ruleChainResultEntity.getAwardId() != null) ruleMatterEntity.setAwardId(ruleChainResultEntity.getAwardId());
        if (ruleChainResultEntity.getGuaranteedAwardId() != null)
            ruleMatterEntity.setGuaranteedAwardId(ruleChainResultEntity.getGuaranteedAwardId());

        // 抽奖后 - 规则过滤
        RuleTreeResultEntity ruleTreeResultEntity = this.doCheckRaffleAfterLogic(ruleMatterEntity, iStrategyRepository.getRuleTreeVO(ruleMatterEntity));

        iStrategyRepository.sendOrder(OrderMessageEntity.builder().strategyId(strategyId).awardId(ruleTreeResultEntity.getAwardId()).userId(userId).build());

        Integer awardId = ruleTreeResultEntity.getAwardId();

        log.info("返回奖品Id：{}", awardId);
        return ok(awardId);
    }

    // 钩子方法：抽奖前 - 责任链过滤
    protected abstract RuleChainResultEntity doCheckRaffleBeforeLogic(RuleMatterEntity ruleMatterEntity);

    // 钩子方法：抽奖后 - 决策树过滤
    protected abstract RuleTreeResultEntity doCheckRaffleAfterLogic(RuleMatterEntity ruleMatterEntity, RuleTreeVO ruleTreeVO);
}
